using System;
using System.Collections.Generic;
using System.Text;

using System.Drawing;
using System.Security.Cryptography;

namespace PictureMimic
{
	public class CandidateGene
	{
		public bool Inbred;
		public bool Mutated;
		
		public Point[] Points;
		public Color Colour;
		
		public CandidateGene()
		{
			// No Parents? No Problems! We will just randomise...

			Inbred = false;
			Mutated = false;

			byte[] seed;
			RNGCryptoServiceProvider seeder;
			Random randomiser;

			seed = new byte[32];
			seeder = new RNGCryptoServiceProvider();
			seeder.GetBytes(seed);

			randomiser = new Random((int)BitConverter.ToInt32(seed, 0));

			int pointCount = randomiser.Next(3, EvolutionaryConstraints.MaxPoints + 1);

			Points = new Point[pointCount];

			for (int i = 0; i < pointCount; i++)
			{
				int x = randomiser.Next(0, EvolutionaryConstraints.EnvironmentWidth + 1);
				int y = randomiser.Next(0, EvolutionaryConstraints.EnvironmentHeight + 1);

				Points[i] = new Point(x, y);
			}

			int a = randomiser.Next(0, 256);
			int r = randomiser.Next(0, 256);
			int g = randomiser.Next(0, 256);
			int b = randomiser.Next(0, 256);

			Colour = Color.FromArgb(a, r, g, b);
		}

		public CandidateGene(CandidateGene source, bool inbred)
		{
			Inbred = inbred;

			// This is not the optimal way to clone the source.
			// The reason I am doing it this way was because I got tired of fighting .NET.
			// Shallow/Deep copies and objects that deny copies... gaaah!
			// Will come back to optimise later.

			Points = new Point[source.Points.Length];

			for (int i = 0; i < source.Points.Length; i++)
			{
				int x = source.Points[i].X;
				int y = source.Points[i].Y;

				Points[i] = new Point(x, y);
			}

			int a = source.Colour.A;
			int r = source.Colour.R;
			int g = source.Colour.G;
			int b = source.Colour.B;

			Colour = Color.FromArgb(a, r, g, b);

			// Will this gene be able to read minds??? We can only hope...
			Mutated = EvolutionaryConstraints.MutationModel.Mutate(this);
		}
	}
}
